save/restore : Save guest's preferred TSC frequency in image
authorKeir Fraser <keir.fraser@citrix.com>
Wed, 24 Jun 2009 09:48:21 +0000 (10:48 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Wed, 24 Jun 2009 09:48:21 +0000 (10:48 +0100)
For save/restore or live migration between two different frequency
platforms, guest's preferred TSC frequency is required to caculate
guest's TSC after resotre, so save it in the image header.

Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
xen/arch/x86/hvm/i8254.c
xen/arch/x86/hvm/save.c
xen/arch/x86/hvm/vpt.c
xen/include/asm-x86/hvm/domain.h
xen/include/asm-x86/hvm/vpt.h
xen/include/public/arch-x86/hvm/save.h

index 2babc2e93d78f7d298c62c4fe4dbbb5785e095df..2d206889bae5992078db03d234ededb2adf88c2a 100644 (file)
@@ -481,8 +481,6 @@ void pit_init(struct vcpu *v, unsigned long cpu_khz)
     register_portio_handler(v->domain, PIT_BASE, 4, handle_pit_io);
     register_portio_handler(v->domain, 0x61, 1, handle_speaker_io);
 
-    ticks_per_sec(v) = cpu_khz * (int64_t)1000;
-
     pit_reset(v->domain);
 }
 
index 6d93340c8b55f498e4337318d0aaaebed2d0be4f..235be64a960423b460477414eda25e7bae279d2a 100644 (file)
@@ -32,7 +32,8 @@ void arch_hvm_save(struct domain *d, struct hvm_save_header *hdr)
     cpuid(1, &eax, &ebx, &ecx, &edx);
     hdr->cpuid = eax;
 
-    hdr->pad0 = 0;
+    /* Save guest's preferred TSC. */
+    hdr->gtsc_khz = d->arch.hvm_domain.gtsc_khz;
 }
 
 int arch_hvm_load(struct domain *d, struct hvm_save_header *hdr)
@@ -59,6 +60,9 @@ int arch_hvm_load(struct domain *d, struct hvm_save_header *hdr)
         gdprintk(XENLOG_WARNING, "HVM restore: saved CPUID (%#"PRIx32") "
                "does not match host (%#"PRIx32").\n", hdr->cpuid, eax);
 
+    /* Restore guest's preferred TSC frequency. */
+    d->arch.hvm_domain.gtsc_khz = hdr->gtsc_khz;
+
     /* VGA state is not saved/restored, so we nobble the cache. */
     d->arch.hvm_domain.stdvga.cache = 0;
 
index 929d4cf57d2a1b07a80614ba61c503732c852566..071ef14517750fa41caa30c2a30cac56cc43f4c3 100644 (file)
@@ -32,6 +32,8 @@ void hvm_init_guest_time(struct domain *d)
     spin_lock_init(&pl->pl_time_lock);
     pl->stime_offset = -(u64)get_s_time();
     pl->last_guest_time = 0;
+
+    d->arch.hvm_domain.gtsc_khz = cpu_khz;
 }
 
 u64 hvm_get_guest_time(struct vcpu *v)
index 0d4aa16028da566920825de53ea97b49e5005258..dc05b5aafef472a0e6b60423782b52b9c32c8746 100644 (file)
@@ -44,7 +44,8 @@ struct hvm_domain {
     struct hvm_ioreq_page  ioreq;
     struct hvm_ioreq_page  buf_ioreq;
 
-    s64                    tsc_frequency;
+    uint32_t               gtsc_khz; /* kHz */
+    uint32_t               pad0;
     struct pl_time         pl_time;
 
     struct hvm_io_handler  io_handler;
index a3384aee9de751be46828e62e57f7e3292455b5d..9f559ea81e17622bbad00cb34b7540c4b8f16bde 100644 (file)
@@ -136,8 +136,6 @@ struct pl_time {    /* platform time */
     spinlock_t pl_time_lock;
 };
 
-#define ticks_per_sec(v) (v->domain->arch.hvm_domain.tsc_frequency)
-
 void pt_save_timer(struct vcpu *v);
 void pt_restore_timer(struct vcpu *v);
 void pt_update_irq(struct vcpu *v);
index d3692d6a86b769538fc7903f2830448e75795626..fd81420439a6d58de923a5f76120eb24ec6c9d4e 100644 (file)
@@ -38,7 +38,7 @@ struct hvm_save_header {
     uint32_t version;           /* File format version */
     uint64_t changeset;         /* Version of Xen that saved this file */
     uint32_t cpuid;             /* CPUID[0x01][%eax] on the saving machine */
-    uint32_t pad0;
+    uint32_t gtsc_khz;        /* Guest's TSC frequency in kHz */
 };
 
 DECLARE_HVM_SAVE_TYPE(HEADER, 1, struct hvm_save_header);